<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="Cask Data, Inc." name="author" />
<meta content="Copyright © 2015-2017 Cask Data, Inc." name="copyright" />


    <meta name="git_release" content="6.1.1">
    <meta name="git_hash" content="05fbac36f9f7aadeb44f5728cea35136dbc243e5">
    <meta name="git_timestamp" content="2020-02-09 08:22:47 +0800">
    <title>Schedules</title>

    <link rel="stylesheet" href="../_static/cdap-bootstrap.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/bootstrap-3.3.6/css/bootstrap.min.css" type="text/css" />
    <link rel="stylesheet" href="../_static/bootstrap-3.3.6/css/bootstrap-theme.min.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/bootstrap-sphinx.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/cdap-dynamicscrollspy-4.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/jquery.mCustomScrollbar.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/cdap-jquery.mCustomScrollbar.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/abixTreeList-2.css" type="text/css" />
    <link rel="stylesheet" href="../_static/cdap-bootstrap.css" type="text/css" />

    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '6.1.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  false
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>

    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="top" title="Cask Data Application Platform 6.1.1 Documentation" href="../index.html" />
    <link rel="up" title="核心概念" href="index.html" />
    <link rel="next" title="Secure Keys" href="secure-keys.html" />
    <link rel="prev" title="Plugins" href="plugins.html" />
    <!-- block extrahead -->
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
    <meta name="apple-mobile-web-app-capable" content="yes">
    <!-- block extrahead end -->

</head>
<body role="document">

<!-- block navbar -->
<div id="navbar" class="navbar navbar-inverse navbar-default navbar-fixed-top">
    <div class="container-fluid">
      <div class="row">
        <div class="navbar-header">
          <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
          <a class="navbar-brand" href="../table-of-contents/../../index.html">
            <span><img alt="CDAP logo" src="../_static/cdap_logo.svg"/></span>
          </a>

          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>

          <div class="pull-right">
            <div class="dropdown version-dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"
                role="button" aria-haspopup="true" aria-expanded="false">
                v 6.1.1 <span class="caret"></span>
              </a>
              <ul class="dropdown-menu">
                <li><a href="//docs.cdap.io/cdap/5.1.2/en/index.html">v 5.1.2</a></li>
                <li><a href="//docs.cdap.io/cdap/4.3.4/en/index.html">v 4.3.4</a></li>
              </ul>
            </div>
          </div>
          <form class="navbar-form navbar-right navbar-search" action="../search.html" method="get">
            <div class="form-group">
              <div class="navbar-search-image material-icons"></div>
              <input type="text" name="q" class="form-control" placeholder="  Search" />
            </div>
            <input type="hidden" name="check_keywords" value="yes" />
            <input type="hidden" name="area" value="default" />
          </form>

          <div class="collapse navbar-collapse nav-collapse navbar-right navbar-navigation">
            <ul class="nav navbar-nav"><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../table-of-contents/../../index.html">简介</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link current" href="../table-of-contents/../../guides.html">手册</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../table-of-contents/../../reference-manual/index.html">参考</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../table-of-contents/../../faqs/index.html">帮助</a></li>
            </ul>
          </div>

        </div>
      </div>
    </div>
  </div><!-- block navbar end -->
<!-- block main content -->
<div class="main-container container">
  <div class="row"><div class="col-md-2">
      <div id="sidebar" class="bs-sidenav scrollable-y-outside" role="complementary">
<!-- theme_manual: developer-manual -->
<!-- theme_manual_highlight: guides -->
<!-- sidebar_title_link: ../table-of-contents/../../guides.html -->

  <div role="note" aria-label="manuals links"><h3><a href="../table-of-contents/../../guides.html">Guides</a></h3>

    <ul class="this-page-menu">
      <li class="toctree-l1"><a href="../table-of-contents/../../user-guide/index.html" rel="nofollow">用户手册</a>
      </li>
      <li class="toctree-l1"><b><a href="../table-of-contents/../../developer-manual/index.html" rel="nofollow">开发手册</a></b>
      <nav class="pagenav">
      <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html"> 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../getting-started/index.html"> 入门指南</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/sandbox/index.html">CDAP Sandbox</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/zip.html">二进制 Zip 文件</a></li>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/zip.html#cdap-sandbox">启动和停止 CDAP Sandbox</a></li>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/virtual-machine.html">虚拟机镜像</a></li>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/docker.html">Docker 镜像</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/quick-start.html">快速入门</a></li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/dev-env.html">搭建开发环境</a></li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/start-stop-cdap.html">启动和停止 CDAP</a></li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/building-apps.html">构建并运行应用</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../overview/index.html"> 概述</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../overview/anatomy.html"> 大数据应用剖析</a></li>
<li class="toctree-l2"><a class="reference internal" href="../overview/modes.html"> 模式和组件</a></li>
<li class="toctree-l2"><a class="reference internal" href="../overview/abstractions.html"> 核心概念</a></li>
<li class="toctree-l2"><a class="reference internal" href="../overview/interfaces.html"> 编程接口</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html"> 抽象概念</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="core.html"> Core Abstractions</a></li>
<li class="toctree-l2"><a class="reference internal" href="applications.html"> Applications</a></li>
<li class="toctree-l2"><a class="reference internal" href="datasets/index.html"> Datasets</a><ul>
<li class="toctree-l3"><a class="reference internal" href="datasets/overview.html"> Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="datasets/table.html"> Table API</a></li>
<li class="toctree-l3"><a class="reference internal" href="datasets/fileset.html"> FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="datasets/partitioned-fileset.html"> Partitioned FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="datasets/time-partitioned-fileset.html"> TimePartitioned FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="datasets/system-custom.html"> System and Custom Datasets</a></li>
<li class="toctree-l3"><a class="reference internal" href="datasets/permissions.html"> Dataset Permissions</a></li>
<li class="toctree-l3"><a class="reference internal" href="datasets/cube.html"> Cube Dataset</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="mapreduce-programs.html"> MapReduce Programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="plugins.html"> Plugins</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"> Schedules</a></li>
<li class="toctree-l2"><a class="reference internal" href="secure-keys.html"> Secure Keys</a></li>
<li class="toctree-l2"><a class="reference internal" href="services.html"> Services</a></li>
<li class="toctree-l2"><a class="reference internal" href="spark-programs.html"> Spark Programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="workers.html"> Workers</a></li>
<li class="toctree-l2"><a class="reference internal" href="workflows.html"> Workflows</a></li>
<li class="toctree-l2"><a class="reference internal" href="artifacts.html"> Artifacts</a></li>
<li class="toctree-l2"><a class="reference internal" href="program-lifecycle.html"> Program Lifecycle</a></li>
<li class="toctree-l2"><a class="reference internal" href="namespaces.html"> Namespaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="transaction-system.html"> Transaction System</a></li>
<li class="toctree-l2"><a class="reference internal" href="transactional-messaging-system.html"> Transactional Messaging System</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../metadata/index.html"> 元数据</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../metadata/system-metadata.html"> System Metadata</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/discovery-lineage.html"> Discovery and Lineage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/field-lineage.html"> Field Level Lineage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/audit-logging.html"> Audit Logging</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/metadata-ui.html"> CDAP Metadata UI</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/programmatic-metadata.html"> Accessing metadata programmatically</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../pipelines/index.html"> 数据流管道</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/concepts-design.html"> Concepts and Design</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/getting-started.html"> Getting Started</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/studio.html"> CDAP Studio</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/creating-pipelines.html"> Creating Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/running-pipelines.html"> Running Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/plugin-management.html"> Plugin Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/plugins/index.html"> Plugin Reference</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/actions/index.html"> Action Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/sources/index.html"> Source Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/transforms/index.html"> Transform Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/analytics/index.html"> Analytic Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/sinks/index.html"> Sink Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/shared-plugins/index.html"> Shared Plugins</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../pipelines/plugins/shared-plugins/core.html">CoreValidator</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/post-run-plugins/index.html"> Post-run Plugins</a><ul class="simple">
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/developing-pipelines.html"> Developing Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/developing-plugins/index.html"> Developing Plugins</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/plugin-basics.html">Plugin Basics</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/creating-a-plugin.html">Creating a Plugin</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/presentation-plugins.html">Plugin Presentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/testing-plugins.html">Testing Plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/packaging-plugins.html">Packaging Plugins</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/how-cdap-pipelines-work.html"> How CDAP Pipelines Work</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../cloud-runtimes/index.html"> 云平台运行</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/concepts/index.html"> Concepts</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/provisioners/index.html"> Provisioners</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/provisioners/gcp-dataproc.html">Google Dataproc</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/provisioners/aws-emr.html">Amazon Elastic MapReduce</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/provisioners/remote-hadoop.html">Remote Hadoop</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/profiles/index.html"> Profiles</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/profiles/creating-profiles.html">Creating Profiles</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/profiles/assigning-profiles.html">Assigning Profiles</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/profiles/admin-controls.html">Admin Controls</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/example/index.html"> Example</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../security/index.html"> 安全</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../security/client-authentication.html">Client Authentication</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/cdap-authentication-clients-java.html">CDAP Authentication Client for Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/cdap-authentication-clients-python.html">CDAP Authentication Client for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/custom-authentication.html">Custom Authentication</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/authorization-extensions.html">Authorization Extensions</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../testing/index.html"> 测试和调试</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../testing/testing.html"> Testing a CDAP Application</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/debugging.html"> Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/troubleshooting.html"> Troubleshooting</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../ingesting-tools/index.html"> 数据融合</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-stream-clients-java.html">CDAP Stream Client for Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-stream-clients-python.html">CDAP Stream Client for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-stream-clients-ruby.html">CDAP Stream Client for Ruby</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-flume.html">CDAP Flume</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../data-exploration/index.html"> 数据探索</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/filesets.html"> Fileset Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/tables.html"> Table Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/object-mapped-tables.html"> ObjectMappedTable Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/custom-datasets.html"> Custom Dataset Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/hive-execution-engines.html"> Hive Execution Engines</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../advanced/index.html"> 高级主题</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../advanced/application-logback.html"> Application Logback</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/best-practices.html"> Best Practices</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/class-loading.html"> Class Loading</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/configuring-resources.html"> Configuring Program Resources</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/program-retry-policies.html"> Program Retry Policies</a></li>
</ul>
</li>
</ul>
</nav>
      </li>
      <li class="toctree-l1"><a href="../table-of-contents/../../admin-manual/index.html" rel="nofollow">管理手册</a>
      </li>
      <li class="toctree-l1"><a href="../table-of-contents/../../integrations/index.html" rel="nofollow">集成手册</a>
      </li>
      <li class="toctree-l1"><a href="../table-of-contents/../../examples-manual/index.html" rel="nofollow">最佳实践</a>
      </li>
    </ul>
  </div></div>
    </div><div class="col-md-8 content" id="main-content">
    
  <div class="section" id="schedules">
<span id="id1"></span><h1>Schedules<a class="headerlink" href="#schedules" title="Permalink to this headline">🔗</a></h1>
<p><em>Schedules</em> are used to automate the execution of <a class="reference internal" href="workflows.html#workflows"><span class="std std-ref">workflows</span></a> on a
recurring time basis, on data availability, on certain statuses reached by another program,
or a logical combination of the conditions mentioned previously. The schedules of an
application can be added as part of application configuration; they can also be managed
through RESTful endpoints that allow listing, modifying, deleting and creating schedules,
as well as disabling and enabling them.</p>
<p>A schedule must have a unique name within its application (the same name can
be used in different applications), and additionally consists of:</p>
<ul class="simple">
<li>the workflow to be executed, along with properties that translate into runtime arguments
for the workflow run;</li>
<li>a <em>Trigger</em>, which initiates the execution of the program by creating a Job for the
workflow;</li>
<li>a set of <em>Run Constraints</em>, which can delay or prevent the execution of the workflow;</li>
<li>a timeout for the run constraints to be fulfilled; when this timeout is exceeded,
the workflow will not execute.</li>
</ul>
<p>To add a schedule to an application extended from <code class="docutils literal notranslate"><span class="pre">AbstractApplication</span></code>, use the method
<a class="reference external" href="../../reference-manual/javadocs/io/cdap/cdap/api/app/AbstractApplication.html#schedule(io.cdap.cdap.internal.schedule.ScheduleCreationSpec)">schedule</a>
. For example, the Purchase example creates a schedule for the PurchaseHistoryWorkflow
as follows:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">schedule</span><span class="p">(</span>
  <span class="n">buildSchedule</span><span class="p">(</span><span class="s">&quot;DailySchedule&quot;</span><span class="p">,</span> <span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;PurchaseHistoryWorkflow&quot;</span><span class="p">)</span>
    <span class="p">.</span><span class="na">withConcurrency</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="na">abortIfNotMet</span><span class="p">()</span>
    <span class="p">.</span><span class="na">triggerByTime</span><span class="p">(</span><span class="s">&quot;0 4 * * *&quot;</span><span class="p">));</span>
</pre></div>
</div>
<p>This schedule uses a time trigger that fires every day at 4:00 am, and it specifies a
concurrency run constraint that will prevent the workflow execution if another run of
the same workflow is executing at that time. Note that:</p>
<ul class="simple">
<li>The buildSchedule method returns a builder to create schedules with various kinds of
triggers and run constraints.</li>
<li>Currently, the only program type that can be scheduled is a workflow.</li>
<li>Replacing <code class="docutils literal notranslate"><span class="pre">abortIfNotMet()</span></code> with <code class="docutils literal notranslate"><span class="pre">waitUntilMet()</span></code> would have the effect that the
workflow execution is delayed until no other concurrent run of the same workflow is
executing.</li>
<li>This schedule does not specify properties for the workflow execution.</li>
<li>This schedule does not configure a timeout, such that the default timeout of one day
is used.</li>
</ul>
<p>If more than one conditions are required to construct the <em>Trigger</em> for the schedule,
to an application extended from <code class="docutils literal notranslate"><span class="pre">AbstractApplication</span></code>, call method <a class="reference external" href="../../reference-manual/javadocs/io/cdap/cdap/api/app/AbstractApplication.html#getTriggerFactory()">getTriggerFactory</a>
to get a <code class="docutils literal notranslate"><span class="pre">TriggerFactory</span></code> to create a specific <em>Trigger</em> as follows:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">schedule</span><span class="p">(</span>
  <span class="n">buildSchedule</span><span class="p">(</span><span class="s">&quot;Workflow1AndWorkflow2CompletedSchedule&quot;</span><span class="p">,</span> <span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;TriggeredWorkflow&quot;</span><span class="p">)</span>
    <span class="p">.</span><span class="na">triggerOn</span><span class="p">(</span><span class="n">getTriggerFactory</span><span class="p">().</span><span class="na">and</span><span class="p">(</span><span class="n">getTriggerFactory</span><span class="p">().</span><span class="na">onProgramStatus</span><span class="p">(</span><span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;Workflow1&quot;</span><span class="p">,</span>
                                                                           <span class="n">ProgramStatus</span><span class="p">.</span><span class="na">COMPLETED</span><span class="p">),</span>
                                       <span class="n">getTriggerFactory</span><span class="p">().</span><span class="na">onProgramStatus</span><span class="p">(</span><span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;Workflow2&quot;</span><span class="p">,</span>
                                                                           <span class="n">ProgramStatus</span><span class="p">.</span><span class="na">COMPLETED</span><span class="p">)));</span>
</pre></div>
</div>
<p>This schedule uses an <cite>and</cite> trigger that can only be satisfied when both Workflow1
is completed and Workflow2 is completed.</p>
<p>Schedules can be added and controlled by the <span class="xref std std-ref">CDAP CLI</span> and the <span class="xref std std-ref">Lifecycle
HTTP RESTful API</span>. The <span class="xref std std-ref">status of a schedule</span> can be retrieved, and individual schedules can be
<span class="xref std std-ref">added</span>,
<span class="xref std std-ref">enabled, or disabled</span>.</p>
<p>When a schedule is initially deployed, it is in a <em>disabled</em> state; it needs to be <em>enabled</em> before
it starts executing workflows.</p>
<div class="section" id="jobs-and-their-lifecycle">
<span id="schedules-jobs-lifecycle"></span><h2>Jobs and their Lifecycle<a class="headerlink" href="#jobs-and-their-lifecycle" title="Permalink to this headline">🔗</a></h2>
<p>Execution of workflows is initiated when the trigger of a schedule fires. This creates
a <em>Job</em> for the workflow in the scheduler’s <em>Job Queue</em>. This job will not necessarily
execute immediately; instead, each job goes through a life cycle:</p>
<ul class="simple">
<li>When a job is initially created, it is in state <em>pending trigger</em>. Most triggers are
fulfilled immediately when the job is created. But some triggers may require additional
input: For example, a partition trigger can specify a minimum number of new partitions
to be present in a dataset. When one or more partitions are added to the dataset, then
this creates an event that leads to the creation of a job. But the number of partitions
may not be sufficient yet, and it would require more partition events until the trigger
is fulfilled. Until then, the job will remain in <em>pending trigger</em> state.</li>
<li>When the job’s trigger is fulfilled, the job’s state changes to <em>pending constraints</em>.
If the job has no constraints, then it will not remain in this state; however, if it
has constraints, then it remains <em>pending constraints</em> until all constraints are fulfilled.
The scheduling system now continuously checks whether its constraints are fulfilled.
During this check, if any constraint is not fulfilled and it was added with
<code class="docutils literal notranslate"><span class="pre">abortIfNotMet()</span></code>, then the job is aborted and removed from the job queue.</li>
<li>When all of a job’s constraints are fulfilled, the job’s state changes to <em>pending launch</em>.
At this time, the scheduling system will prepare the execution of the workflow, and once
it is started successfully, the job is complete and removed from the job queue. Note that
the workflow itself can still fail during its execution, but if the scheduler
successfully submitted the workflow for execution, then the job is considered complete from
the scheduler’s point of view. If starting the workflow fails, however, the job remains
<em>pending launch</em> and the system will retry execution.</li>
<li>If a job does not reach <em>pending launch</em> state before its configured timeout, it is
aborted and removed from the job queue.</li>
<li>If a schedule is deleted, modified or disabled, then all jobs for that schedule are
aborted and removed from the job queue, regardless of their state. However, due to
timing and concurrency, a job that is <em>pending launch</em> may still execute around the same
time that the schedule was modified.</li>
<li>At any given time, there is only one job in state <em>pending trigger</em> or <em>pending constraints</em>
for a given schedule. That means that if the schedule’s trigger fires again, it does not
create a new job in the job queue. Only after the job transitions into <em>pending launch</em>
state can the schedule’s trigger create a new job.</li>
</ul>
</div>
<div class="section" id="events-and-notifications">
<span id="schedules-events"></span><h2>Events and Notifications<a class="headerlink" href="#events-and-notifications" title="Permalink to this headline">🔗</a></h2>
<p>Triggers are fired by events such as creation of a new partition in a dataset, or
fulfillment of a cron expression of a time trigger, or the status of a program.
Events reach the scheduling system as notifications on the Transactional Messaging System (TMS).
A single notification can contain multiple events, for example, two new partitions for a dataset.
For a time trigger, the event contains the logical start time, that is, the time when the cron
expression fired. This logical start time is given to the workflow as a runtime argument.
For a program status trigger, the event contains the triggering program status and
the triggering program run id.</p>
</div>
<div class="section" id="run-constraints">
<span id="schedules-run-constraints"></span><h2>Run Constraints<a class="headerlink" href="#run-constraints" title="Permalink to this headline">🔗</a></h2>
<p>A run constraint can either delay or prevent the execution of a schedule’s workflow, based
on a condition represented by the constraint. The default behavior of whether the execution
is delayed or aborted is different for each type of run constraint—it can be configured
explicitly by specifying either <code class="docutils literal notranslate"><span class="pre">.waitUntilMet()</span></code> or <code class="docutils literal notranslate"><span class="pre">.abortIfNotMet()</span></code>
when adding the constraint to the schedule builder. Every individual type of run constraint
also has its own default for this behavior. These constraints are available:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">withConcurrency(int</span> <span class="pre">n)</span></code>: Fulfilled if less than n runs of the same workflow are
currently executing. This is useful to limit the frequency and resource utilization
of a single workflow. By default, this aborts the job if not fulfilled.</li>
<li><code class="docutils literal notranslate"><span class="pre">withDelay(long</span> <span class="pre">n,</span> <span class="pre">TimeUnit</span> <span class="pre">unit)</span></code>: Fulfilled at least n time units after the job
is created. This is useful to delay the execution of a workflow after its trigger
fires, for example, if it is known that after some new data arrives, more new data
may arrive within short time, and the workflow should wait for that.</li>
<li><code class="docutils literal notranslate"><span class="pre">withTimeWindow(String</span> <span class="pre">startTime,</span> <span class="pre">String</span> <span class="pre">endTime)</span></code>: Fulfilled only in the time
window between the given start and end time. Both times are given in “HH:mm” form,
and an optional timezone can be given to interpret these times. By default, this
delays the execution of the job, but it can be configured to abort the job
if the trigger fires outside the time window. This is useful to limit the execution
of certain workflows to times when the load on the cluster is low.</li>
<li><code class="docutils literal notranslate"><span class="pre">withDurationSinceLastRun(long</span> <span class="pre">n,</span> <span class="pre">TimeUnit</span> <span class="pre">unit)</span></code>: Fulfilled only after n time
units since the start of the last successful run of the same workflow. This is useful
to limit the frequency of execution of the workflow. By default, this aborts the
execution if not met.</li>
</ul>
</div>
<div class="section" id="triggers">
<span id="schedules-triggers"></span><h2>Triggers<a class="headerlink" href="#triggers" title="Permalink to this headline">🔗</a></h2>
<p>A trigger can be based on time or data availability, These are the available trigger types:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">time</span></code>: This is triggered every time the cron expression
is met. A time trigger is fulfilled immediately, allowing the job to transition into
<em>pending constraints</em> state right away. When the workflow executes, the time at which
the cron expression was fulfilled is passed to the workflow as its logical start time.</li>
<li><code class="docutils literal notranslate"><span class="pre">partition</span></code>: This is triggered by new partitions in the named dataset (it must be a
<code class="docutils literal notranslate"><span class="pre">PartitionedFileSet</span></code> or a <code class="docutils literal notranslate"><span class="pre">TimePartitionedFileSet</span></code>). While a single notification for
new partitions in the dataset suffices to to create a job for the schedule, it will
remain in <em>pending trigger</em> state until enough partitions have arrived to exceed
the <code class="docutils literal notranslate"><span class="pre">numPartitions</span></code> parameter.</li>
<li><code class="docutils literal notranslate"><span class="pre">program</span> <span class="pre">status</span></code>: This is triggered when a given program in the specific namespace,
application, and application version transitions to any one of the given program statuses.</li>
<li><code class="docutils literal notranslate"><span class="pre">and</span></code>: This is triggered when all the triggers contained in it are satisfied.</li>
<li><code class="docutils literal notranslate"><span class="pre">or</span></code>: This is triggered when any of the given triggers contained in it is/are satisfied.</li>
</ul>
</div>
<div class="section" id="examples">
<span id="schedules-examples"></span><h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">🔗</a></h2>
<p>To schedule a workflow whenever a new partition is added to a dataset, but delay execution
to the time window between 10pm and 6am:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span>schedule(buildSchedule(&quot;runOnlyAtNight&quot;, ProgramType.WORKFLOW, &quot;cleanupWorkflow&quot;)
           .withTimeWindow(&quot;22:00&quot;, &quot;06:00”).waitUntilMet()
           .triggerOnPartitions(&quot;myDataset&quot;, 1));
</pre></div>
</div>
<p>The same as before, but ensure that it runs only once in that time window:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span>schedule(buildSchedule(&quot;runOnlyAtNight&quot;, ProgramType.WORKFLOW, &quot;cleanupWorkflow&quot;)
           .withTimeWindow(&quot;22:00&quot;, &quot;06:00”).waitUntilMet()
           .withDurationSinceLastRun(6, TimeUnit.HOURS).abortIfNotMet()
           .triggerOnPartitions(&quot;myDataset&quot;, 1));
</pre></div>
</div>
<p>To schedule a workflow whenever there are four new partitions, with 15 minutes delay
to allow additional data to arrive:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">schedule</span><span class="p">(</span><span class="n">buildSchedule</span><span class="p">(</span><span class="s">&quot;onPartitionWithDelay&quot;</span><span class="p">,</span> <span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;myWorkflow&quot;</span><span class="p">)</span>
           <span class="p">.</span><span class="na">withDelay</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="n">TimeUnit</span><span class="p">.</span><span class="na">MINUTES</span><span class="p">)</span>
           <span class="p">.</span><span class="na">triggerOnPartitions</span><span class="p">(</span><span class="s">&quot;myDataset&quot;</span><span class="p">,</span> <span class="mi">4</span><span class="p">));</span>
</pre></div>
</div>
<p>To schedule a workflow named “cleanupWorkflow” to run whenever “dataProcessingWorkflow”
(in the same namespace, application, and application version as “cleanupWorkflow”)
fails:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">schedule</span><span class="p">(</span><span class="n">buildSchedule</span><span class="p">(</span><span class="s">&quot;onDataProcessingFail&quot;</span><span class="p">,</span> <span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;cleanupWorkflow&quot;</span><span class="p">)</span>
            <span class="p">.</span><span class="na">triggerOnProgramStatus</span><span class="p">(</span><span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;dataProcessingWorkflow&quot;</span><span class="p">,</span>
                                    <span class="n">ProgramStatus</span><span class="p">.</span><span class="na">FAILED</span><span class="p">);</span>
</pre></div>
</div>
<p>To ensure that the workflow runs at least once per hour:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">schedule</span><span class="p">(</span><span class="n">buildSchedule</span><span class="p">(</span><span class="s">&quot;onPartitionWithDelay&quot;</span><span class="p">,</span> <span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;myWorkflow&quot;</span><span class="p">)</span>
           <span class="p">.</span><span class="na">setProperties</span><span class="p">(</span><span class="n">ImmutableMap</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;triggered.by&quot;</span><span class="p">,</span> <span class="s">&quot;data&quot;</span><span class="p">))</span>
           <span class="p">.</span><span class="na">withDelay</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="n">TimeUnit</span><span class="p">.</span><span class="na">MINUTES</span><span class="p">)</span>
           <span class="p">.</span><span class="na">withConcurrency</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="na">abortIfNotMet</span><span class="p">()</span>
           <span class="p">.</span><span class="na">triggerOnPartitions</span><span class="p">(</span><span class="s">&quot;myDataset&quot;</span><span class="p">,</span> <span class="mi">4</span><span class="p">));</span>
<span class="n">schedule</span><span class="p">(</span><span class="n">buildSchedule</span><span class="p">(</span><span class="s">&quot;onceHourly&quot;</span><span class="p">,</span> <span class="n">ProgramType</span><span class="p">.</span><span class="na">WORKFLOW</span><span class="p">,</span> <span class="s">&quot;myWorkflow&quot;</span><span class="p">)</span>
           <span class="p">.</span><span class="na">setProperties</span><span class="p">(</span><span class="n">ImmutableMap</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;triggered.by&quot;</span><span class="p">,</span> <span class="s">&quot;time&quot;</span><span class="p">))</span>
           <span class="p">.</span><span class="na">withConcurrency</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="na">abortIfNotMet</span><span class="p">()</span>
           <span class="p">.</span><span class="na">withDurationSinceLastRun</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">TimeUnit</span><span class="p">.</span><span class="na">HOURS</span><span class="p">).</span><span class="na">abortIfNotMet</span><span class="p">()</span>
           <span class="p">.</span><span class="na">triggerByTime</span><span class="p">(</span><span class="s">&quot;0 * * * *&quot;</span><span class="p">));</span>
</pre></div>
</div>
<p>We added another schedule that runs once hourly, but only if no other run of the workflow
in the last hour succeeded and no concurrent run is happening. We also add the concurrency
constraint to the first schedule to make sure it does not kick off when the second schedule is
just executing a job.</p>
<p>Note that through the properties we can indicate to the workflow which schedule triggered
it—we could also pass arbitrary other properties.</p>
</div>
<div class="section" id="managing-schedules">
<span id="schedules-manage"></span><h2>Managing Schedules<a class="headerlink" href="#managing-schedules" title="Permalink to this headline">🔗</a></h2>
<p class="rubric">Schedules Lifecycle</p>
<p>These actions can be performed on a schedule:</p>
<ul class="simple">
<li><em>Create</em>: This happens either as part of application deployment or through the Lifecycle HTTP
RESTful API. After creating a schedule, it is initially disabled and will not execute any jobs.</li>
<li><em>Disable</em>: Disabling a schedule will delete all pending jobs for the schedule from the job
queue, and prevent new jobs from being created. This action will not suspend or abort any
current execution of the workflow.</li>
<li><em>Enable</em>: This action will put the schedule back into an active state, after a <em>Disable</em>
action. Note that if the schedule was previously disabled, that aborted all pending jobs
for the schedule. Therefore new triggers have to create new jobs for this schedule before
its workflow is executed again.</li>
<li><em>Delete</em>: This first disables the schedule and then permanently deletes it.</li>
<li><em>Update</em>: This is equivalant to deleting the current schedule and creating a new one. It happens
either when an application which contains a schedule is redeployed in CDAP, or through the
Lifecycle HTTP RESTful API.</li>
</ul>
<p class="rubric">Application Deployment and Schedules</p>
<p>Schedules can be defined as part of application deployment, by calling <code class="docutils literal notranslate"><span class="pre">schedule()</span></code>
in the application’s <code class="docutils literal notranslate"><span class="pre">configure()</span></code> method; or they can be managed separately from
application deployment through the HTTP RESTful API. This can create a dilemma: After
modifiying schedules through REST, redeploying the application, which may happen for
reasons unrelated to the schedules, would undo all those changes and reinstate the schedules
defined by the <code class="docutils literal notranslate"><span class="pre">configure()</span></code> method. Because that is undesired, CDAP provides an option
to configure whether schedules are controlled by the <code class="docutils literal notranslate"><span class="pre">configure()</span></code> method or not. This
option is called <code class="docutils literal notranslate"><span class="pre">app.deploy.update.schedules</span></code> and is given as a field of the
<span class="xref std std-ref">application deployment request</span>.</p>
<ul class="simple">
<li>If this option is true, then application deployment will replace all schedules for
the application with the schedules given by the <code class="docutils literal notranslate"><span class="pre">configure()</span></code> method;</li>
<li>if it is false, application deployment will not change any schedules, except that if
the application is updated, all schedules for programs that do not exist any longer
after the update are deleted.</li>
</ul>
<p class="rubric">Special Runtime Arguments</p>
<p>When a schedule with a time trigger executes a workflow it passes in the <code class="docutils literal notranslate"><span class="pre">logicalStartTime</span></code>
runtime argument: this is the timestamp, in milliseconds, at which the schedule’s cron expression
was fulfilled and triggered the job.</p>
</div>
</div>

</div>
    <div class="col-md-2">
      <div id="right-sidebar" class="bs-sidenav scrollable-y" role="complementary">
        <div id="localtoc-scrollspy">
        </div>
      </div>
    </div></div>
</div>
<!-- block main content end -->
<!-- block footer -->
<footer class="footer">
      <div class="container">
        <div class="row">
          <div class="col-md-2 footer-left"><a title="Plugins" href="plugins.html" />Previous</a></div>
          <div class="col-md-8 footer-center"><a class="footer-tab-link" href="../table-of-contents/../../reference-manual/licenses/index.html">Copyright</a> &copy; 2014-2020 Cask Data, Inc.&bull; <a class="footer-tab-link" href="//docs.cask.co/cdap/6.1.1/cdap-docs-6.1.1-web.zip" rel="nofollow">Download</a> an archive or
<a class="footer-tab-link" href="//docs.cask.co/cdap">switch the version</a> of the documentation
          </div>
          <div class="col-md-2 footer-right"><a title="Secure Keys" href="secure-keys.html" />Next</a></div>
        </div>
      </div>
    </footer>
<!-- block footer end -->
<script type="text/javascript" src="../_static/bootstrap-3.3.6/js/bootstrap.min.js"></script><script type="text/javascript" src="../_static/js/bootstrap-sphinx.js"></script><script type="text/javascript" src="../_static/js/abixTreeList-2.js"></script><script type="text/javascript" src="../_static/js/cdap-dynamicscrollspy-4.js"></script><script type="text/javascript" src="../_static/js/cdap-version-menu.js"></script><script type="text/javascript" src="../_static/js/copy-to-clipboard.js"></script><script type="text/javascript" src="../_static/js/jquery.mousewheel.min.js"></script><script type="text/javascript" src="../_static/js/jquery.mCustomScrollbar.js"></script><script type="text/javascript" src="../_static/js/js.cookie.js"></script><script type="text/javascript" src="../_static/js/tabbed-parsed-literal-0.2.js"></script><script type="text/javascript" src="../_static/js/cdap-onload-javascript.js"></script><script type="text/javascript" src="../_static/js/cdap-version-menu.js"></script>
    <script src="https://cdap.gitee.io/docs/cdap/json-versions.js"/></script>
  </body>
</html>